home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 125
/
Freelog_MarsAvril2015_No125.iso
/
Musique
/
Quod Libet
/
quodlibet-3.3.0-installer.exe
/
bin
/
quodlibet
/
ext
/
events
/
animosd.pyc
(
.txt
)
< prev
next >
Wrap
Python Compiled Bytecode
|
2014-12-31
|
24KB
|
617 lines
# Source Generated with Decompyle++
# File: in.pyc (Python 2.7)
from collections import namedtuple
import gi
gi.require_version('PangoCairo', '1.0')
from gi.repository import Gtk, GObject, GLib
from gi.repository import Gdk, GdkPixbuf
from gi.repository import Pango, PangoCairo
import cairo
from math import pi
from quodlibet import config, qltk, app
from quodlibet.qltk.textedit import PatternEdit
from quodlibet.formats import DUMMY_SONG
from quodlibet import parse
from quodlibet.plugins.events import EventPlugin
from quodlibet.plugins import PluginConfigMixin
from quodlibet.util.dprint import print_d, print_w
from quodlibet.util import connect_obj
class ConfigLabel(Gtk.Label):
'''Customised Label for configuration, tied to a widget'''
def __init__(self, text, widget):
super(Gtk.Label, self).__init__(label = text, use_underline = True)
self.set_mnemonic_widget(widget)
self.set_alignment(0, 0.5)
class OSDWindow(Gtk.Window):
__gsignals__ = {
'fade-finished': (GObject.SignalFlags.RUN_LAST, None, (bool,)) }
def __init__(self, conf, song):
Gtk.Window.__init__(self, Gtk.WindowType.POPUP)
self.set_type_hint(Gdk.WindowTypeHint.NOTIFICATION)
screen = self.get_screen()
rgba = screen.get_rgba_visual()
if rgba is not None:
self.set_visual(rgba)
self.conf = conf
self.iteration_source = None
self.fading_in = False
self.fade_start_time = 0
cover = song.find_cover()
try:
if cover is not None:
cover = GdkPixbuf.Pixbuf.new_from_file(cover.name)
except GLib.GError:
gerror = None
print_w('GDK error while loading cover image: %s' % gerror.message)
except:
format_exc = format_exc
import traceback
print_w('Error loading cover image: %s' % format_exc())
mgeo = screen.get_monitor_geometry(conf.monitor)
coverwidth = min(120, mgeo.width // 8)
textwidth = mgeo.width - 2 * (conf.border + conf.margin)
if cover is not None:
textwidth -= coverwidth + conf.border
coverheight = int(cover.get_height() * float(coverwidth) / cover.get_width())
else:
coverheight = 0
self.cover_pixbuf = cover
layout = self.create_pango_layout('')
layout.set_alignment((Pango.Alignment.LEFT, Pango.Alignment.CENTER, Pango.Alignment.RIGHT)[conf.align])
layout.set_spacing(Pango.SCALE * 7)
layout.set_font_description(Pango.FontDescription(conf.font))
try:
layout.set_markup(parse.XMLFromMarkupPattern(conf.string) % song)
except parse.error:
layout.set_markup('')
layout.set_width(Pango.SCALE * textwidth)
layoutsize = layout.get_pixel_size()
if layoutsize[0] < textwidth:
layout.set_width(Pango.SCALE * layoutsize[0])
layoutsize = layout.get_pixel_size()
self.title_layout = layout
winw = layoutsize[0] + 2 * conf.border
if cover is not None:
winw += coverwidth + conf.border
winh = max(coverheight, layoutsize[1]) + 2 * conf.border
self.set_default_size(winw, winh)
rect = namedtuple('Rect', [
'x',
'y',
'width',
'height'])
rect.x = conf.border
rect.y = (winh - coverheight) // 2
rect.width = coverwidth
rect.height = coverheight
self.cover_rectangle = rect
winx = int((mgeo.width - winw) * conf.pos_x)
winx = max(conf.margin, min(mgeo.width - conf.margin - winw, winx))
winy = int((mgeo.height - winh) * conf.pos_y)
winy = max(conf.margin, min(mgeo.height - conf.margin - winh, winy))
self.move(winx + mgeo.x, winy + mgeo.y)
def do_draw(self, cr):
if self.is_composited():
self.draw_title_info(cr)
else:
walloc = self.get_allocation()
wpos = self.get_position()
if not getattr(self, '_bg_sf', None):
root_win = self.get_root_window()
bg_sf = cairo.ImageSurface(cairo.FORMAT_ARGB32, walloc.width, walloc.height)
pb = Gdk.pixbuf_get_from_window(root_win, wpos[0], wpos[1], walloc.width, walloc.height)
bg_cr = cairo.Context(bg_sf)
Gdk.cairo_set_source_pixbuf(bg_cr, pb, 0, 0)
bg_cr.paint()
self._bg_sf = bg_sf
if not getattr(self, '_fg_sf', None):
fg_sf = cairo.ImageSurface(cairo.FORMAT_ARGB32, walloc.width, walloc.height)
fg_cr = cairo.Context(fg_sf)
fg_cr.set_source_surface(fg_sf)
self.draw_title_info(fg_cr)
self._fg_sf = fg_sf
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.set_source_surface(self._bg_sf)
cr.paint()
cr.set_operator(cairo.OPERATOR_OVER)
cr.set_source_surface(self._fg_sf)
cr.paint_with_alpha(self.get_opacity())
def rounded_rectangle(cr, x, y, radius, width, height):
cr.move_to(x + radius, y)
cr.line_to(x + width - radius, y)
cr.arc(x + width - radius, y + radius, radius, -90 * pi / 180, 0 * pi / 180)
cr.line_to(x + width, y + height - radius)
cr.arc(x + width - radius, y + height - radius, radius, 0 * pi / 180, 90 * pi / 180)
cr.line_to(x + radius, y + height)
cr.arc(x + radius, y + height - radius, radius, 90 * pi / 180, 180 * pi / 180)
cr.line_to(x, y + radius)
cr.arc(x + radius, y + radius, radius, 180 * pi / 180, 270 * pi / 180)
cr.close_path()
rounded_rectangle = staticmethod(rounded_rectangle)
def draw_conf_rect(self, cr, x, y, width, height, radius):
if self.conf.corners != 0:
self.rounded_rectangle(cr, x, y, radius, width, height)
else:
cr.rectangle(x, y, width, height)
def draw_title_info(self, cr):
cr.save()
do_shadow = self.conf.shadow[0] != -1
do_outline = self.conf.outline[0] != -1
self.set_name('osd_bubble')
qltk.add_css(self, '\n #osd_bubble {\n background-color:rgba(0,0,0,0);\n }\n ')
cr.set_operator(cairo.OPERATOR_OVER)
cr.set_source_rgba(*self.conf.fill)
radius = min(25, self.conf.corners * min(*self.get_size()))
self.draw_conf_rect(cr, 0, 0, self.get_size()[0], self.get_size()[1], radius)
cr.fill()
if do_outline:
f = self.conf.fill
rgba = (f[0] / 1.25, f[1] / 1.25, f[2] / 1.25, f[3] / 2)
cr.set_source_rgba(*rgba)
self.draw_conf_rect(cr, 1, 1, self.get_size()[0] - 2, self.get_size()[1] - 2, radius)
cr.set_line_width(2)
cr.stroke()
textx = self.conf.border
if self.cover_pixbuf is not None:
rect = self.cover_rectangle
textx += rect.width + self.conf.border
pbuf = self.cover_pixbuf
transmat = cairo.Matrix()
if do_shadow:
cr.set_source_rgba(*self.conf.shadow)
self.draw_conf_rect(cr, rect.x + 2, rect.y + 2, rect.width, rect.height, 0.6 * self.conf.corners * rect.width)
cr.fill()
if do_outline:
cr.set_source_rgba(*self.conf.outline)
self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.conf.corners * rect.width)
cr.stroke()
Gdk.cairo_set_source_pixbuf(cr, pbuf, 0, 0)
transmat.scale(pbuf.get_width() / float(rect.width), pbuf.get_height() / float(rect.height))
transmat.translate(-(rect.x), -(rect.y))
cr.get_source().set_matrix(transmat)
self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.conf.corners * rect.width)
cr.fill()
PangoCairo.update_layout(cr, self.title_layout)
height = self.title_layout.get_pixel_size()[1]
texty = (self.get_size()[1] - height) // 2
if do_shadow:
cr.set_source_rgba(*self.conf.shadow)
cr.move_to(textx + 2, texty + 2)
PangoCairo.show_layout(cr, self.title_layout)
if do_outline:
cr.set_source_rgba(*self.conf.outline)
cr.move_to(textx, texty)
PangoCairo.layout_path(cr, self.title_layout)
cr.stroke()
cr.set_source_rgb(*self.conf.text[:3])
cr.move_to(textx, texty)
PangoCairo.show_layout(cr, self.title_layout)
cr.restore()
def fade_in(self):
self.do_fade_inout(True)
def fade_out(self):
self.do_fade_inout(False)
def do_fade_inout(self, fadein):
fadein = bool(fadein)
self.fading_in = fadein
now = GObject.get_current_time()
fraction = self.get_opacity()
if not fadein:
fraction = 1 - fraction
self.fade_start_time = now - fraction * self.conf.fadetime
if self.iteration_source is None:
self.iteration_source = GLib.timeout_add(self.conf.ms, self.fade_iteration_callback)
def fade_iteration_callback(self):
delta = GObject.get_current_time() - self.fade_start_time
fraction = delta / self.conf.fadetime
if self.fading_in:
self.set_opacity(fraction)
else:
self.set_opacity(1 - fraction)
if not self.is_composited():
self.queue_draw()
if fraction >= 1:
self.iteration_source = None
self.emit('fade-finished', self.fading_in)
return False
class AnimOsd(EventPlugin, PluginConfigMixin):
PLUGIN_ID = 'Animated On-Screen Display'
PLUGIN_NAME = _('Animated On-Screen Display')
PLUGIN_DESC = _('Display song information on your screen when it changes.')
PLUGIN_VERSION = '1.3'
CONFIG_SECTION = 'animosd'
def PluginPreferences(self, parent):
def _AnimOsd__coltofloat(x):
return x / 65535
def _AnimOsd__floattocol(x):
return int(x * 65535)
def cfg_set_tuple(name, t):
s = ' '.join(map(str, t))
self.config_set('%s' % name, s)
def show_preview():
preview_song = app.player.song if app.player.song else DUMMY_SONG
self.plugin_on_song_started(preview_song)
def on_button_pressed(x = None, y = (None,)):
show_preview()
def set_text(button):
color = button.get_color()
color = map(_AnimOsd__coltofloat, (color.red, color.green, color.blue, 0))
self.Conf.text = tuple(color)
cfg_set_tuple('text', self.Conf.text)
show_preview()
def set_fill(button):
color = button.get_color()
color = map(_AnimOsd__coltofloat, (color.red, color.green, color.blue, button.get_alpha()))
self.Conf.fill = tuple(color)
cfg_set_tuple('fill', self.Conf.fill)
show_preview()
def set_font(button):
font = button.get_font_name()
self.config_set('font', font)
self.Conf.font = font
show_preview()
def change_delay(button):
value = int(button.get_value() * 1000)
self.config_set('delay', str(value))
self.Conf.delay = value
def change_monitor(button):
'''Monitor number config change handler'''
value = int(button.get_value())
self.config_set('monitor', str(value))
self.Conf.monitor = value
show_preview()
def change_position(button):
value = button.get_active() / 2
self.config_set('pos_y', str(value))
self.Conf.pos_y = value
show_preview()
def change_align(button):
value = button.get_active()
self.config_set('align', str(value))
self.Conf.align = value
show_preview()
def change_shadow(button):
if button.get_active():
self.Conf.shadow = (0, 0, 0, self.Conf.fill[3])
else:
self.Conf.shadow = (-1, 0, 0, 0)
cfg_set_tuple('shadow', self.Conf.shadow)
show_preview()
def change_outline(button):
if button.get_active():
alpha = min(1, self.Conf.fill[3] * 1.25)
self.Conf.outline = (0.1, 0.1, 0.1, alpha)
else:
self.Conf.outline = (-1, 0, 0)
cfg_set_tuple('outline', self.Conf.outline)
show_preview()
def change_rounded(button):
if button.get_active():
self.Conf.corners = 0.14
else:
self.Conf.corners = 0
self.config_set('corners', str(self.Conf.corners))
show_preview()
def edit_pattern(button):
w = PatternEdit(button, AnimOsd.ConfDef.string)
w.set_default_size(520, 260)
w.text = self.Conf.string
connect_obj(w.apply, 'clicked', set_string, w)
w.show()
def set_string(window):
value = window.text
self.config_set('string', value)
self.Conf.string = value
show_preview()
vb = Gtk.VBox(spacing = 6)
def build_display_widget():
vb2 = Gtk.VBox(spacing = 3)
hb = Gtk.HBox(spacing = 6)
monitor_cnt = Gdk.Screen.get_default().get_n_monitors()
if monitor_cnt > 1:
adj = Gtk.Adjustment(value = self.Conf.monitor, lower = 0, upper = monitor_cnt - 1, step_incr = 1)
monitor = Gtk.SpinButton(adjustment = adj)
monitor.set_numeric(True)
monitor.connect('value-changed', change_monitor)
l2 = ConfigLabel('_Monitor:', monitor)
hb.pack_start(l2, False, True, 0)
hb.pack_start(monitor, False, True, 0)
vb2.pack_start(hb, True, True, 0)
else:
self.Conf.monitor = 0
hb = Gtk.HBox(spacing = 6)
cb = Gtk.ComboBoxText()
cb.append_text(_('Top of screen'))
cb.append_text(_('Middle of screen'))
cb.append_text(_('Bottom of screen'))
cb.set_active(int(self.Conf.pos_y * 2))
cb.connect('changed', change_position)
lbl = ConfigLabel(_('_Position:'), cb)
hb.pack_start(lbl, False, True, 0)
hb.pack_start(cb, False, True, 0)
vb2.pack_start(hb, False, True, 0)
return vb2
frame = qltk.Frame(label = _('Display'), child = build_display_widget())
frame.set_border_width(6)
vb.pack_start(frame, False, True, 0)
def build_text_widget():
t = Gtk.Table(n_rows = 2, n_columns = 2)
t.set_col_spacings(6)
t.set_row_spacings(3)
font = Gtk.FontButton(show_style = True)
font.set_font_name(self.Conf.font)
font.connect('font-set', set_font)
lbl = ConfigLabel(_('_Font:'), font)
t.attach(lbl, 0, 1, 0, 1, xoptions = Gtk.AttachOptions.FILL)
t.attach(font, 1, 2, 0, 1)
align = Gtk.ComboBoxText()
align.append_text(_('Left'))
align.append_text(_('Center'))
align.append_text(_('Right'))
align.set_active(self.Conf.align)
align.connect('changed', change_align)
lbl = ConfigLabel(_('_Align text:'), align)
t.attach(lbl, 0, 1, 1, 2, xoptions = Gtk.AttachOptions.FILL)
t.attach(align, 1, 2, 1, 2)
return t
frame = qltk.Frame(label = _('Text'), child = build_text_widget())
frame.set_border_width(6)
vb.pack_start(frame, False, True, 0)
def build_colors_widget():
t = Gtk.Table(n_rows = 2, n_columns = 2)
t.set_col_spacings(6)
t.set_row_spacings(3)
b = Gtk.ColorButton(rgba = Gdk.RGBA(*map(_AnimOsd__floattocol, self.Conf.text)))
l = ConfigLabel(_('_Text:'), b)
t.attach(l, 0, 1, 0, 1, xoptions = Gtk.AttachOptions.FILL)
t.attach(b, 1, 2, 0, 1)
b.connect('color-set', set_text)
b = Gtk.ColorButton(color = Gdk.Color(*map(_AnimOsd__floattocol, self.Conf.fill[0:3])))
b.set_use_alpha(True)
b.set_alpha(_AnimOsd__floattocol(self.Conf.fill[3]))
b.connect('color-set', set_fill)
l = ConfigLabel(_('_Fill:'), b)
t.attach(l, 0, 1, 1, 2, xoptions = Gtk.AttachOptions.FILL)
t.attach(b, 1, 2, 1, 2)
return t
f = qltk.Frame(label = _('Colors'), child = build_colors_widget())
f.set_border_width(6)
vb.pack_start(f, False, False, 0)
def build_effects_widget():
vb2 = Gtk.VBox(spacing = 3)
hb = Gtk.HBox(spacing = 6)
toggles = [
(_('_Shadows'), self.Conf.shadow[0], change_shadow),
(_('_Outline'), self.Conf.outline[0], change_outline),
(_('Rou_nded Corners'), self.Conf.corners - 1, change_rounded)]
for label, current, callback in toggles:
checkb = Gtk.CheckButton(label = label, use_underline = True)
checkb.set_active(current != -1)
checkb.connect('toggled', callback)
hb.pack_start(checkb, True, True, 0)
vb2.pack_start(hb, True, True, 0)
hb = Gtk.HBox(spacing = 6)
timeout = Gtk.SpinButton(adjustment = Gtk.Adjustment.new(self.Conf.delay / 1000, 0, 60, 0.1, 1, 0), climb_rate = 0.1, digits = 1)
timeout.set_numeric(True)
timeout.connect('value-changed', change_delay)
l1 = ConfigLabel(_('_Delay:'), timeout)
hb.pack_start(l1, False, True, 0)
hb.pack_start(timeout, False, True, 0)
vb2.pack_start(hb, False, True, 0)
return vb2
frame = qltk.Frame(label = _('Effects'), child = build_effects_widget())
frame.set_border_width(6)
vb.pack_start(frame, False, True, 0)
def build_buttons_widget():
hb = Gtk.HBox(spacing = 6)
edit_button = qltk.Button(_('Ed_it Display Pattern...'), Gtk.STOCK_EDIT)
edit_button.connect('clicked', edit_pattern)
hb.pack_start(edit_button, False, True, 0)
preview_button = Gtk.Button(label = _('Preview'))
preview_button.connect('button-press-event', on_button_pressed)
hb.pack_start(preview_button, False, True, 0)
return hb
vb.pack_start(build_buttons_widget(), False, True, 0)
return vb
class ConfDef(object):
pos_x = 0.5
pos_y = 0
margin = 50
border = 20
fadetime = 0.3
ms = 40
delay = 2500
monitor = 0
font = 'Sans 22'
text = (0.9, 0.9, 0.9, 0)
align = 1
corners = 0
outline = (-1, 0, 0, 0.2)
shadow = (-1, 0, 0, 0.1)
fill = (0.25, 0.25, 0.25, 0.5)
bcolor = (0, 0, 0, 0.2)
string = "<album|[b]<album>[/b]<discnumber| - Disc <discnumber>><part| - [b]<part>[/b]><tracknumber| - <tracknumber>>\n>[span weight='bold' size='large']<title>[/span] - <~length><version|\n[small][i]<version>[/i][/small]><~people|\nby <~people>>"
Conf = ConfDef()
def __init__(self):
self._AnimOsd__current_window = None
def str_to_tuple(s):
lst = map(float, s.split())
while len(lst) < 4:
lst.append(0)
return tuple(lst)
config_map = [
('text', str_to_tuple),
('fill', str_to_tuple),
('shadow', str_to_tuple),
('outline', str_to_tuple),
('bcolor', str_to_tuple),
('corners', float),
('font', None),
('align', int),
('delay', int),
('monitor', int),
('pos_y', float),
('string', None)]
for key, getconv in config_map:
try:
default = getattr(self.Conf, key)
except AttributeError:
print_d("Unknown config item '%s'" % key)
try:
value = self.config_get(key, default)
if value is None:
continue
except (config.Error, ValueError):
print_d("Couldn't find config item %s" % key)
continue
try:
if getconv is not None:
value = getconv(value)
except Exception:
err = None
print_d('Error parsing config for %s (%s) - defaulting to %r' % (key, err, default))
if default is not None:
self.config_set(key, default)
setattr(self.Conf, key, value)
def plugin_on_song_started(self, song):
if self._AnimOsd__current_window is not None:
if self._AnimOsd__current_window.is_composited():
self._AnimOsd__current_window.fade_out()
else:
self._AnimOsd__current_window.hide()
self._AnimOsd__current_window.destroy()
if song is None:
self._AnimOsd__current_window = None
return None
window = None(self.Conf, song)
window.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
window.connect('button-press-event', self._AnimOsd__buttonpress)
window.connect('fade-finished', self._AnimOsd__fade_finished)
self._AnimOsd__current_window = window
window.set_opacity(0)
window.show()
window.fade_in()
def plugin_on_error(self, song, error):
if self._AnimOsd__current_window is not None:
self._AnimOsd__current_window.destroy()
self._AnimOsd__current_window = None
def start_fade_out(window):
window.fade_out()
return False
start_fade_out = staticmethod(start_fade_out)
def __buttonpress(self, window, event):
window.hide()
if self._AnimOsd__current_window is window:
self._AnimOsd__current_window = None
window.destroy()
def __fade_finished(self, window, fade_in):
if fade_in:
GLib.timeout_add(self.Conf.delay, self.start_fade_out, window)
else:
window.hide()
if self._AnimOsd__current_window is window:
self._AnimOsd__current_window = None
GLib.timeout_add(1000, window.destroy)